package com.sparrow.source.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.sparrow.source.common.CommonConstant;
import com.sparrow.source.common.dto.DesktopReport;
import com.sparrow.source.common.dto.FeiYouVerificationReport;
import com.sparrow.source.common.dto.ReportDeviceChannel;
import com.sparrow.source.common.dto.ReportTable;
import com.sparrow.source.common.dto.ReportTableRequest;
import com.sparrow.source.common.enums.ChannelEnums;
import com.sparrow.source.common.utils.RedisUtils;
import com.sparrow.source.persistense.IasUser;
import com.sparrow.source.persistense.IasVerifyReport;
import com.sparrow.source.persistense.UnvDevice;
import com.sparrow.source.persistense.mapper.IasVerifyReportMapper;
import com.sparrow.source.service.IIasUserService;
import com.sparrow.source.service.IIasVerifyReportService;
import com.sparrow.source.service.IUnvDeviceService;
import com.sun.org.apache.bcel.internal.generic.LSTORE;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

import static com.sparrow.source.common.RabbitConstant.FEIYOU_EXCHANGE_BUS;
import static com.sparrow.source.common.RabbitConstant.PEOPLE_VERIFY_REPORT_QUEUE;
import static com.sparrow.source.common.RabbitConstant.PEOPLE_VERIFY_REPORT_QUEUE_ROUTE_KEY;

/**
 * @author bryceyung
 * @since 2024/11/25
 */
@Service
@Slf4j
public class IasVerifyReportServiceImpl extends ServiceImpl<IasVerifyReportMapper, IasVerifyReport> implements IIasVerifyReportService {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private IUnvDeviceService deviceService;

    @Autowired
    private IIasUserService userService;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private Executor threadPoolTaskExecutor;

    @Override
    public Boolean saveReport(IasVerifyReport report) {
        threadPoolTaskExecutor.execute(() -> {
            UnvDevice device = deviceService.getById(report.getDeviceId());
            String checkKey = CommonConstant.REDIS_CHECK_IN_OUT_KEY + device.getSerialNumber() + report.getUid();
            //判断重复打卡
            String checkTypeFlag = "CHECK_TYPE_" + device.getSerialNumber() + report.getUid();
            if (redisUtils.getObject(checkTypeFlag) != null) {
                report.setMatchRes(30);
            }
            if (redisUtils.getObject(checkKey) == null) {
                //上班打卡
                report.setCheckType(1);
            } else {
                Integer checkVal = Integer.valueOf(redisUtils.getObject(checkKey));
                if (checkVal % 2 == 0) {
                    report.setCheckType(1);
                } else {
                    report.setCheckType(2);
                }
            }
            this.save(report);
            FeiYouVerificationReport verificationReport = reportConvert(report);
            rabbitTemplate.convertAndSend(FEIYOU_EXCHANGE_BUS, PEOPLE_VERIFY_REPORT_QUEUE_ROUTE_KEY, JSONObject.toJSONString(verificationReport));
        });
        return report.getId() != null;
    }

    @Override
    public Boolean haveCheckedInCurdate(String deviceCode, Integer channelFlag, Long uid) {
        //channelFlag 为1 的设备----》直接上班打卡
        UnvDevice device = deviceService.lambdaQuery().eq(UnvDevice::getSerialNumber, deviceCode).one();
        if (device != null && device.getChannelFlag().equals(1)) {
            return true;
        }
        return baseMapper.haveCheckedInCurdate(channelFlag, uid);
    }

    @Override
    public IPage<ReportTable> queryReportTable(ReportTableRequest reportTableRequest, Page<ReportTable> page) {
        return baseMapper.selectReportTable(reportTableRequest.getBeginTime(), reportTableRequest.getEndTime(), reportTableRequest.getDeviceName(),
                reportTableRequest.getUserName(), reportTableRequest.getCheckType(), reportTableRequest.getMatchRes(), page);
    }

    @Override
    public Map<String, List<ReportDeviceChannel>> queryDeviceChannel() {
        Map<String, List<ReportDeviceChannel>> map = Maps.newConcurrentMap();
        map.put(CommonConstant.REPORT_WORK_CHECK, baseMapper.selectDeviceChannel(1));
        map.put(CommonConstant.REPORT_CHANNEL_CHECK, baseMapper.selectDeviceChannel(2));
        return map;
    }

    @Override
    public List<ReportDeviceChannel> queryCheckCountWeekly() {
        return baseMapper.selectCheckCountWeekly();
    }

    @Override
    public Boolean updateOnlineStatus(String deviceCode, Boolean status) {
        UnvDevice device = deviceService.lambdaQuery().eq(UnvDevice::getSerialNumber, deviceCode).eq(UnvDevice::getDeleted,false).one();
        if (device == null) {
            log.error("updateOnlineStatus 未查询到设备信息:[{}]", deviceCode);
            return false;
        }
        device.setOnlineStatus(status);
        device.setSyncTime(new Date());
        return deviceService.updateById(device);
    }

    @Override
    public DesktopReport getDesktopReport() {
        DesktopReport desktopReport = new DesktopReport();
        List<UnvDevice> deviceList = deviceService.lambdaQuery().eq(UnvDevice::getDeleted, false).list();
        desktopReport.setTotalDevice(deviceList.size());
        desktopReport.setOnlineDevice((int) deviceList.stream().filter(UnvDevice::getOnlineStatus).count());
        List<ReportDeviceChannel> checkList = baseMapper.selectCheckCountWeekly();
        desktopReport.setCheckInCount(checkList.get(checkList.size() - 1).getResult());
        return desktopReport;
    }

    @Override
    public List<ReportDeviceChannel> queryCurrDate(String beginDate, String endDate, Integer deviceId) {
        return baseMapper.selectCurrDateCheck(beginDate, endDate, deviceId);
    }

    public FeiYouVerificationReport reportConvert(IasVerifyReport report) {
        FeiYouVerificationReport verificationReport = new FeiYouVerificationReport();
        UnvDevice device = deviceService.getById(report.getDeviceId());
        if (device == null) {
            return verificationReport;
        }
        //        verificationReport.setId(report.getId());
        verificationReport.setChannel(device.getChannel());
        verificationReport.setChannelName(ChannelEnums.getByChannel(device.getChannel()).getChannelName());
        verificationReport.setChannelFlag(device.getChannelFlag());
        verificationReport.setDeviceName(device.getName());
        verificationReport.setMatchResult(report.getMatchRes());
        verificationReport.setReportTime(report.getReportTime());
        verificationReport.setDeviceSerialNumber(device.getSerialNumber());
        IasUser user = userService.queryByUserOrPersonId(report.getUid());
        if (user == null) {
            return verificationReport;
        }
        verificationReport.setUid(user.getUid());
        verificationReport.setUserName(user.getName());
        verificationReport.setPersonId(user.getPersonId());
        verificationReport.setFaceData(report.getFaceData());
        return verificationReport;
    }
}
